package com.tripwego.server.service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.tripwego.client.service.EtapeDao;
import com.tripwego.server.jdo.ActiviteJdo;
import com.tripwego.server.jdo.EtapeJdo;
import com.tripwego.server.jdo.PositionJdo;
import com.tripwego.server.jdo.TrajetJdo;
import com.tripwego.shared.dto.ActiviteDto;
import com.tripwego.shared.dto.EtapeDto;
import com.tripwego.shared.dto.PositionDto;

/**
 * @author jguibert
 * 
 *         CRUD EtapeDao
 */
public class JdoEtapeDao extends RemoteServiceServlet implements EtapeDao {
	private static final Logger log = Logger.getLogger(JdoEtapeDao.class.getName());

	private static final long serialVersionUID = 1L;

	private PersistenceManager pm = PMF.get().getPersistenceManager();

	// private Transaction tx;

	@Override
	public Long create(EtapeDto etapeDto) {
		log.info("DEB - create");

		EtapeJdo entity = new EtapeJdo();
		entity.setTripId(etapeDto.getTripId());
		entity.setAddress(etapeDto.getAddress());
		entity.setDateDeb(etapeDto.getDateDeb());
		entity.setDateFin(etapeDto.getDateFin());
		entity.setFirstStep(etapeDto.isFirstStep());
		entity.setIconUrl(etapeDto.getIconUrl());
		entity.setName(etapeDto.getName());
		entity.setOrder(etapeDto.getOrder());

		entity.setDateCreation(new Date());
		entity.setDateModification(new Date());

		PositionJdo positionJdo = new PositionJdo(etapeDto.getPosition());
		entity.setPosition(positionJdo);

		// tx = pm.currentTransaction();
		// tx.begin();

		// pm.makePersistent(positionJdo);
		pm.makePersistent(entity);

		// tx.commit();		
		
		log.info("FIN - create");

		return entity.getKey().getId();
	}

	@Override
	public void update(EtapeDto etapeDto) {
		log.info("DEB - update");

		EtapeJdo entity = (EtapeJdo) pm.getObjectById(EtapeJdo.class, etapeDto.getId());

		// entity.setAddress(etapeDto.getAddress());
		entity.setDateDeb(etapeDto.getDateDeb());
		entity.setDateFin(etapeDto.getDateFin());
		// entity.setFirstStep(etapeDto.isFirstStep());
		// entity.setIconUrl(etapeDto.getIconUrl());
		// entity.setLatitude(etapeDto.getLatitude());
		// entity.setLongitude(etapeDto.getLongitude());
		entity.setName(etapeDto.getName());
		// entity.setOrder(etapeDto.getOrder());
		// entity.setTravelMode(etapeDto.getTravelMode());

		entity.setDateModification(new Date());

		// tx = pm.currentTransaction();
		// tx.begin();

		pm.makePersistent(entity);

		// tx.commit();

		log.info("FIN - update");
	}

	@Override
	public void delete(EtapeDto etapeDto) {
		log.info("DEB - delete");

		// tx = pm.currentTransaction();
		// tx.begin();

		EtapeJdo entity = (EtapeJdo) pm.getObjectById(EtapeJdo.class, etapeDto.getId());
		pm.deletePersistent(entity);

		// tx.commit();

		log.info("FIN - delete");
	}

	@Override
	public List<EtapeDto> findByTripId(Long tripId) {
		log.info("DEB - findByTripId");

		List<EtapeDto> liste = new ArrayList<EtapeDto>();

		Query query = pm.newQuery(EtapeJdo.class, "tripId == " + tripId);
		query.setOrdering("order");

		try {
			List<EtapeJdo> results = (List<EtapeJdo>) query.execute();
			if (results.iterator().hasNext()) {
				for (EtapeJdo entity : results) {

					EtapeDto etapeDto = new EtapeDto();

					etapeDto.setAddress(entity.getAddress());
					etapeDto.setDateDeb(entity.getDateDeb());
					etapeDto.setDateFin(entity.getDateFin());
					etapeDto.setFirstStep(entity.isFirstStep());
					etapeDto.setIconUrl(entity.getIconUrl());
					etapeDto.setId(entity.getKey().getId());

					PositionDto positionDtoEtape = new PositionDto();
					positionDtoEtape.setId(entity.getPosition().getKey().getId());
					positionDtoEtape.setLatitude(entity.getPosition().getLatitude());
					positionDtoEtape.setLongitude(entity.getPosition().getLongitude());
					positionDtoEtape.setType(entity.getPosition().getType());
					etapeDto.setPosition(positionDtoEtape);

					etapeDto.setName(entity.getName());
					etapeDto.setOrder(entity.getOrder());
					etapeDto.setTripId(entity.getTripId());

					List<ActiviteDto> listActiviteDto = new ArrayList<ActiviteDto>();

					// restitution des activites
					for (ActiviteJdo activiteJdo : entity.getListActivite()) {
						ActiviteDto activiteDto = new ActiviteDto();

						activiteDto.setEtapeId(entity.getKey().getId());
						activiteDto.setAddress(activiteJdo.getAddress());
						activiteDto.setDateDeb(activiteJdo.getDateDeb());
						activiteDto.setDateFin(activiteJdo.getDateFin());
						activiteDto.setIconUrl(activiteJdo.getIconUrl());
						activiteDto.setId(activiteJdo.getKey().getId());

						PositionDto positionDtoActivite = new PositionDto();
						positionDtoActivite.setId(entity.getPosition().getKey().getId());
						positionDtoActivite.setLatitude(activiteJdo.getPosition().getLatitude());
						positionDtoActivite.setLongitude(activiteJdo.getPosition().getLongitude());
						positionDtoActivite.setType(activiteJdo.getPosition().getType());
						etapeDto.setPosition(positionDtoActivite);

						activiteDto.setName(activiteJdo.getName());

						listActiviteDto.add(activiteDto);
					}

					etapeDto.setListActivite(listActiviteDto);

					liste.add(etapeDto);
				}
			} else {
				log.info("findByTripId : No results");
			}
		} finally {
			query.closeAll();
		}

		log.info("FIN - findByTripId");

		return liste;
	}

	public static int dateDiff(Date d1, Date d2) {

		Calendar cal1 = Calendar.getInstance();
		Calendar cal2 = Calendar.getInstance();

		cal1.setTime(d1);
		cal2.setTime(d2);
		cal1.set(Calendar.HOUR_OF_DAY, 0);
		cal1.set(Calendar.MINUTE, 0);
		cal1.set(Calendar.SECOND, 0);
		cal1.set(Calendar.MILLISECOND, 0);
		cal2.set(Calendar.HOUR_OF_DAY, 0);
		cal2.set(Calendar.MINUTE, 0);
		cal2.set(Calendar.SECOND, 0);
		cal2.set(Calendar.MILLISECOND, 0);

		return (int) ((cal2.getTimeInMillis() - cal1.getTimeInMillis()) / (24 * 60 * 60 * 1000)) + 1;
	}
}
